package com.supermarket.service;

import com.supermarket.exception.UserException;
import com.supermarket.mapper.UserMapper;
import com.supermarket.entity.User;
import com.supermarket.entity.Rider;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.supermarket.common.RedisUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Date;
import java.math.BigDecimal;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.lang.Validator;
import java.util.Set;

@Service
public class UserService {

    @Resource
    private UserMapper userMapper;
    
    @Resource
    private RiderService riderService;
    
    @Resource
    private RedisUtil redisUtil;
    
    // Redis缓存相关的Key前缀
    private static final String USER_KEY_PREFIX = "user:info:";
    private static final String USER_LIST_KEY = "user:list";
    private static final int USER_CACHE_SECONDS = 14400; // 用户缓存默认4小时

    /**
     * 获取所有用户信息
     * 
     * @return 用户列表
     */
    public List<User> getAllUser() {
        // 尝试从缓存中获取用户列表
        Object cached = redisUtil.get(USER_LIST_KEY);
        if (cached != null) {
            return (List<User>) cached;
        }
        
        // 缓存未命中，从数据库获取
        List<User> userList = userMapper.selectAllUsers();
        
        // 将结果存入缓存
        if (userList != null && !userList.isEmpty()) {
            redisUtil.set(USER_LIST_KEY, userList, USER_CACHE_SECONDS);
        }
        
        return userList;
    }

    /**
     * 分页查询所有用户
     *
     * @param pageNum  当前页码
     * @param pageSize 每页显示条数
     * @param username 用户名（可选）
     * @param nickname 昵称（可选）
     * @param email    邮箱（可选）
     * @return 包含分页结果的 Map
     */
    public Map<String, Object> getAllUsersWithPagination(int pageNum, int pageSize, String username, String nickname, String email) {
        // 生成缓存key
        String cacheKey = generateUserListCacheKey(pageNum, pageSize, username, nickname, email);
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (Map<String, Object>) cached;
        }
        
        // 缓存未命中，查询数据库
        PageHelper.startPage(pageNum, pageSize);
        List<User> users = userMapper.selectAllUsersWithPagination(username, nickname, email);
        PageInfo<User> pageInfo = new PageInfo<>(users);

        Map<String, Object> result = new HashMap<>();
        result.put("list", pageInfo.getList());
        result.put("total", pageInfo.getTotal());
        
        // 将结果存入缓存，设置较短的过期时间，因为是分页数据
        redisUtil.set(cacheKey, result, 1800); // 30分钟
        
        return result;
    }

    /**
     * 根据用户ID查询用户信息
     * 
     * @param id 用户ID
     * @return 用户对象
     */
    public User getUserById(Integer id) {
        String cacheKey = USER_KEY_PREFIX + id;
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (User) cached;
        }
        
        // 缓存未命中，查询数据库
        User user = userMapper.selectUserById(id);
        
        // 将结果存入缓存
        if (user != null) {
            redisUtil.set(cacheKey, user, USER_CACHE_SECONDS);
        }
        
        return user;
    }

    /**
     * 根据用户名查询用户信息
     * 
     * @param username 用户名
     * @return 用户对象
     */
    public User getUserByUsername(String username) {
        String cacheKey = USER_KEY_PREFIX + "username:" + username;
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (User) cached;
        }
        
        // 缓存未命中，查询数据库
        User user = userMapper.selectUserByUsername(username);
        
        // 将结果存入缓存
        if (user != null) {
            redisUtil.set(cacheKey, user, USER_CACHE_SECONDS);
        }
        
        return user;
    }

    /**
     * 根据用户属性查询用户信息
     * 
     * @param user 用户对象，包含查询条件
     * @return 符合条件的用户列表
     */
    public List<User> selectByUser(User user) {
        // System.out.println(user.toString());
        return userMapper.selectByUser(user);
    }

    /**
     * 添加新用户
     * 
     * @param user 用户对象
     * @return 影响的行数
     */
    @Transactional
    public int addUser(User user) {
        if (user.getScore()==null){
            user.setScore(0);
        }
        if (user.getRole() == null) {
            user.setRole("USER");
        }
        if (StrUtil.isBlank(user.getUsername()) || StrUtil.isBlank(user.getPassword()) || StrUtil.isBlank(user.getNickname())) {
            throw new UserException("账号、密码和昵称不能为空");
        }
        if (Validator.hasChinese(user.getUsername())) {
            throw new UserException("账号不能包含中文");
        }
        if (Validator.hasChinese(user.getPassword())) {
            throw new UserException("密码不能包含中文");
        }
        if (userMapper.selectUserByUsername(user.getUsername()) != null) {
            throw new UserException("用户已存在");
        }
        
        // 插入用户信息
        int result = userMapper.insertUser(user);
        
        // 如果是骑手角色，创建骑手信息
        if ("RIDER".equals(user.getRole())) {
            Integer userId = userMapper.selectUserByUsername(user.getUsername()).getId();
            Rider rider = new Rider();
            rider.setUserId(userId);
            rider.setStatus("AVAILABLE");
            rider.setDeliveryCount(0);
            rider.setRating(new BigDecimal("5.0"));
            rider.setCreateTime(new Date());
            rider.setUpdateTime(new Date());
            
            // 创建骑手记录
            riderService.createRider(rider);
        }
        
        // 清除用户列表缓存
        clearUserListCache();
        
        return result;
    }

    /**
     * 更新用户信息
     * 
     * @param user 用户对象
     * @return 影响的行数
     */
    public int updateUser(User user) {
        if (user.getScore()==null){
            user.setScore(0);
        }
        if (StrUtil.isBlank(user.getUsername()) || StrUtil.isBlank(user.getNickname())) {
            throw new UserException("账号和昵称不能为空");
        }
        if (Validator.hasChinese(user.getUsername())) {
            throw new UserException("账号不能包含中文");
        }
        if (Validator.hasChinese(user.getPassword())) {
            throw new UserException("密码不能包含中文");
        }
        int result = userMapper.updateUser(user);
        if (result == 0) {
            throw new RuntimeException("更新失败，数据已被其他事务修改");
        }
        
        // 更新缓存
        clearUserCache(user.getId(), user.getUsername());
        clearUserListCache();
        
        return result;
    }

    /**
     * 删除用户
     * 
     * @param username 用户名
     * @return 影响的行数
     */
    public int deleteUser(String username) {
        User user = getUserByUsername(username);
        int result = userMapper.deleteUser(username);
        
        // 删除成功后，清除缓存
        if (result > 0 && user != null) {
            clearUserCache(user.getId(), username);
            clearUserListCache();
        }
        
        return result;
    }

    /**
     * 用户登录
     *
     * @param user 用户对象
     * @return 登录成功的用户对象
     */
    public User Login(User user) {
        if(StrUtil.isBlank(user.getUsername())){
            UserException e = new UserException("账号不能为空");
            e.setUserId(0);
            throw e;
        }
        User dbUser = getUserByUsername(user.getUsername());
        if (dbUser == null) {
            UserException e = new UserException("账号不存在");
            e.setUserId(0);
            throw e;
        }
        if (!dbUser.getPassword().equals(user.getPassword())) {
            UserException e = new UserException("密码错误");
            e.setUserId(dbUser.getId());
            throw e;
        }
        if (!dbUser.getRole().equals(user.getRole())) {
            UserException e = new UserException("账户身份错误");
            e.setUserId(dbUser.getId());
            throw e;
        }
        return dbUser;
    }

    /**
     * 统计用户总数
     *
     * @return 用户总数
     */
    public int countUsers() {
        String cacheKey = "user:count";
        
        // 尝试从缓存获取
        Object cached = redisUtil.get(cacheKey);
        if (cached != null) {
            return (int) cached;
        }
        
        // 缓存未命中，查询数据库
        int count = userMapper.countUsers();
        
        // 将结果存入缓存，设置较短的过期时间
        redisUtil.set(cacheKey, count, 1800); // 30分钟
        
        return count;
    }
    
    /**
     * 生成用户列表缓存Key
     */
    private String generateUserListCacheKey(int pageNum, int pageSize, String username, String nickname, String email) {
        StringBuilder sb = new StringBuilder(USER_LIST_KEY);
        sb.append(":page").append(pageNum);
        sb.append(":size").append(pageSize);
        
        if (!StrUtil.isBlank(username)) {
            sb.append(":u").append(username);
        }
        if (!StrUtil.isBlank(nickname)) {
            sb.append(":n").append(nickname);
        }
        if (!StrUtil.isBlank(email)) {
            sb.append(":e").append(email);
        }
        
        return sb.toString();
    }
    
    /**
     * 清除用户缓存
     */
    private void clearUserCache(Integer id, String username) {
        if (id != null) {
            redisUtil.delete(USER_KEY_PREFIX + id);
        }
        if (username != null) {
            redisUtil.delete(USER_KEY_PREFIX + "username:" + username);
        }
    }
    
    /**
     * 清除用户列表缓存
     */
    private void clearUserListCache() {
        // 删除用户列表相关的所有缓存
        Set<String> keys = redisUtil.keys(USER_LIST_KEY + "*");
        if (keys != null && !keys.isEmpty()) {
            redisUtil.delete(keys);
        }
        
        // 删除用户计数缓存
        redisUtil.delete("user:count");
    }
}